import {
  Accordion,
  AccordionContent,
  AccordionItem,
  AccordionTrigger,
} from '@/components/ui/accordion';
import { Button } from '@/components/ui/button';
import { Calendar } from '@/components/ui/calendar';
import { Input } from '@/components/ui/input';
import { Label } from '@/components/ui/label';
import { Popover, PopoverContent, PopoverTrigger } from '@/components/ui/popover';
import { Sheet, SheetContent, SheetHeader, SheetTitle, SheetTrigger } from '@/components/ui/sheet';
import config from '@/config';
import {
  AvaliableItem,
  getAvaliableCategoryReduction,
  getCategoryAvaliableByDay,
  getSkuInfoAvaliableByDay,
} from '@/lib/gigaAvaliable';
import { cn } from '@/lib/utils';
import { useGigaNotPersisStore } from '@/store/gigaNotPersist';
import { format } from 'date-fns';
import { CalendarIcon } from 'lucide-react';
import { useId } from 'react';
import { toast } from 'sonner';
import useLocalStorage from '../hook/useLocalStorage';

type Props = {
  children?: React.ReactNode;
  className?: string;
};

export interface AvaliableDayChange {
  skuInfo: string;
  dayChange: number;
  todayAvaliable: number;
  dayAvaliable: Array<{
    timeStamp: number;
    day: string;
    avaliable: number;
  }>;
}

export default function AvaliableDayChangeStatistics({ children, className, ...props }: Props) {
  const [avaliableDayChange, setAvaliableDayChange] = useState<
    Record<string, AvaliableDayChange[]>
  >({});
  const [today, setToday] = useState<Date | undefined>(new Date());
  const categoryTree = useGigaNotPersisStore((state) => state.categoryTree);
  const [expandedItems, setExpandedItems] = useState<string[]>([]);
  const [isRunning, setIsRunning] = useState(false);
  const [storeValue, setStoreValue] = useLocalStorage<{
    minTodayAvaliable: number;
    minDayChange: number;
    dayInterval: number;
    prefixSkuInfoFilter: string;
  }>('avaliable-day-statistics', {
    minTodayAvaliable: 50,
    minDayChange: 3,
    prefixSkuInfoFilter: 'B,T',
    dayInterval: 7,
  });

  const todayStamp = useMemo(() => {
    if (today) {
      return today.getTime();
    } else {
      return new Date().getTime();
    }
  }, [today]);
  async function getAvaliableDayChange() {
    const sortCategoryNames = Object.keys(categoryTree).sort((itemA, itemB) => {
      return itemA.localeCompare(itemB);
    });
    for (const sortCategoryName of sortCategoryNames) {
      // 当天分类下的库存
      let avaliableCategoryTodayAvaliable = await getCategoryAvaliableByDay(
        todayStamp,
        sortCategoryName,
      );

      // 找到符合数量的产品
      avaliableCategoryTodayAvaliable = avaliableCategoryTodayAvaliable.filter(
        (item) => item.avaliable >= storeValue.minTodayAvaliable,
      );

      let avaliableCategoryDayChange: AvaliableDayChange[] = await Promise.all(
        avaliableCategoryTodayAvaliable.map(async (item) => {
          const dayAvaliable: AvaliableDayChange['dayAvaliable'] = await Promise.all(
            Array.from({
              length: storeValue.dayInterval,
            }).map(async (_, index) => {
              const result = await getSkuInfoAvaliableByDay(
                item.skuInfo,
                todayStamp - (index + 1) * 24 * 60 * 60 * 1000,
                sortCategoryName,
              );
              if (result) {
                return {
                  timeStamp: result.timeStamp,
                  day: new Date(result.timeStamp).toLocaleDateString(),
                  avaliable: result.avaliable,
                };
              } else {
                return {
                  timeStamp: 0,
                  day: '',
                  avaliable: NaN,
                };
              }
            }),
          );
          // 加上第一天
          dayAvaliable.unshift({
            day: new Date(item.timeStamp).toLocaleDateString(),
            avaliable: item.avaliable,
            timeStamp: item.timeStamp,
          });
          return {
            skuInfo: item.skuInfo,
            dayChange: 0,
            todayAvaliable: item.avaliable,
            dayAvaliable: dayAvaliable,
          };
        }),
      );

      // console.log(avaliableCategoryDayChange);
      // 计算变化天数
      avaliableCategoryDayChange.forEach((item) => {
        const dayAvaliables = item.dayAvaliable
          .map((item) => item.avaliable)
          .filter((item) => {
            return !Number.isNaN(item);
          });
        let dayChange = 0;
        dayAvaliables.forEach((item, index) => {
          if (index < dayAvaliables.length - 1) {
            if (dayAvaliables[index] !== dayAvaliables[index + 1]) {
              dayChange++;
            }
          }
        });
        item.dayChange = dayChange;
      });

      console.log(avaliableCategoryDayChange);

      // 过滤掉变化天数不足的货号
      avaliableCategoryDayChange = avaliableCategoryDayChange.filter((item) => {
        return item.dayChange >= storeValue.minDayChange;
      });

      // 过滤掉不要的货号
      avaliableCategoryDayChange = avaliableCategoryDayChange.filter((item) => {
        const prefixList = storeValue.prefixSkuInfoFilter.split(',').map((prefex) => {
          return prefex.trim();
        });
        return !prefixList.some((prefex) => {
          return item.skuInfo.startsWith(prefex);
        });
      });

      setAvaliableDayChange((prev) => {
        return {
          ...prev,
          [sortCategoryName]: avaliableCategoryDayChange,
        };
      });
      if (avaliableCategoryDayChange.length > 0) {
        setExpandedItems((prev) => [...prev, sortCategoryName]);
      }
    }
  }
  const id = useId();
  return (
    <div className={className} {...props}>
      <Sheet modal={false}>
        <SheetTrigger asChild>{children}</SheetTrigger>
        <SheetContent
          className="!max-w-[60vw] flex flex-col w-auto"
          style={{
            zIndex: config.sheetZIndex,
          }}
        >
          <SheetHeader>
            <SheetTitle>库存变化天数统计</SheetTitle>
            <span className="text-xs">
              (计算方式是挑选当前日期库存量大于特定设置数值的货号,并且货号对比前一天有变化的天数大于特定设置天数)
            </span>
          </SheetHeader>
          <div className="mt-2">
            <div className="flex gap-2 items-center">
              <span className="mr-3">选择当前日期: </span>
              <Popover>
                <PopoverTrigger asChild>
                  <Button
                    size={'sm'}
                    variant={'outline'}
                    className={cn('justify-start text-left font-normal')}
                  >
                    <CalendarIcon />
                    {today ? format(today, 'PPP') : <span>选择当前日期</span>}
                  </Button>
                </PopoverTrigger>
                <PopoverContent
                  className="w-auto p-0"
                  style={{
                    zIndex: config.alertDialogZIndex,
                  }}
                >
                  <Calendar mode="single" selected={today} onSelect={setToday} />
                </PopoverContent>
              </Popover>
              <div className="flex gap-2 items-center py-2 mr-3">
                <Label className="whitespace-nowrap" htmlFor={id + '-day-interval'}>
                  前缀货号过滤:
                </Label>
                <Input
                  value={storeValue.prefixSkuInfoFilter}
                  onChange={(event) => {
                    setStoreValue((prev) => {
                      return {
                        ...prev,
                        prefixSkuInfoFilter: event.target.value,
                      };
                    });
                  }}
                  id={id + '-day-interval'}
                  className="h-10 w-[120px] rounded-md border border-input px-3 py-2"
                />
              </div>
              <div className="mt-2 flex items-center">
                <div className="flex gap-2 items-center py-2 mr-3">
                  <Label className="whitespace-nowrap" htmlFor={id + '-day-interval'}>
                    对比第几天前的库存:
                  </Label>
                  <Input
                    value={storeValue.dayInterval}
                    type="number"
                    onChange={(event) => {
                      setStoreValue((prev) => {
                        return {
                          ...prev,
                          dayInterval: +event.target.value,
                        };
                      });
                    }}
                    id={id + '-day-interval'}
                    className="h-10 w-[80px] rounded-md border border-input px-3 py-2"
                  />
                </div>
              </div>
            </div>
            <div className="flex items-center">
              <div className="flex gap-2 items-center py-2 mr-3">
                <Label className="whitespace-nowrap" htmlFor={id + '-min-today-avaliable'}>
                  当前日期的最少库存:
                </Label>
                <Input
                  value={storeValue.minTodayAvaliable}
                  type="number"
                  onChange={(event) => {
                    setStoreValue((prev) => {
                      return {
                        ...prev,
                        minTodayAvaliable: +event.target.value,
                      };
                    });
                  }}
                  id={id + '-min-today-avaliable'}
                  className="h-10 w-[120px] rounded-md border border-input px-3 py-2"
                />
              </div>
              <div className="flex gap-2 items-center py-2">
                <Label className="whitespace-nowrap" htmlFor={id + '-min-day-change'}>
                  最少变化天数:
                </Label>
                <Input
                  value={storeValue.minDayChange}
                  type="number"
                  onChange={(event) => {
                    setStoreValue((prev) => {
                      return {
                        ...prev,
                        minDayChange: +event.target.value,
                      };
                    });
                  }}
                  id={id + '-min-day-change'}
                  className="h-10 w-[120px]  rounded-md border border-input px-3 py-2"
                />
              </div>
              <Button
                onClick={async () => {
                  if (isRunning) {
                    toast.info('正在统计中...');
                  }
                  setIsRunning(true);
                  await getAvaliableDayChange();
                  setIsRunning(false);
                  toast.success('统计完成');
                }}
                size="sm"
                className="ml-auto hover:bg-[#337AB7] bg-[#428BCA]"
              >
                开始统计{isRunning ? '(统计中...)' : ''}
              </Button>
            </div>
          </div>
          <div className="grow overflow-auto">
            <Accordion
              type="multiple"
              className="w-full"
              value={expandedItems}
              onValueChange={setExpandedItems}
            >
              {Object.keys(avaliableDayChange).map((categoryName, index) => {
                return (
                  <div key={categoryName} className="leading-loose py-1">
                    <AccordionItem value={categoryName}>
                      <AccordionTrigger className="flex items-center gap-2 justify-start py-0 !flex-nowrap">
                        <div className="whitespace-nowrap">{categoryName}</div>
                      </AccordionTrigger>
                      <AccordionContent className="pl-4">
                        {avaliableDayChange[categoryName].map((item) => {
                          return (
                            <div key={item.skuInfo} className="my-1">
                              <span>{item.skuInfo}: </span>
                              <span>
                                当前库存:{' '}
                                <span className="text-green-700">{item.todayAvaliable}</span>
                              </span>
                              <span
                                className="ml-1"
                                title={item.dayAvaliable
                                  .filter((item) => {
                                    return !Number.isNaN(item.avaliable);
                                  })
                                  .map((item) => {
                                    return `${item.day}: ${item.avaliable}`;
                                  })
                                  .join('\n')}
                              >
                                日期变化数: <span className="text-green-700">{item.dayChange}</span>
                              </span>
                            </div>
                          );
                        })}
                      </AccordionContent>
                    </AccordionItem>
                  </div>
                );
              })}
            </Accordion>
          </div>
        </SheetContent>
      </Sheet>
    </div>
  );
}
